# backend/app/main.py

"""
@File    :   main.py
@Time    :   2024/10/15 00:46:24
@Author  :   chen 
@Version :   1.0
@Contact :   chenjianshengcjs@126.com
@desc    :   用于编写服务器demo,方便后续编写接口测试的框架
"""

import asyncio  # 引入 asyncio 用于异步操作
import io
from fastapi import FastAPI, Request, HTTPException, status
from fastapi.exceptions import RequestValidationError
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import JSONResponse, StreamingResponse
import uvicorn
import os
import logging
from datetime import datetime
import sys

# 设置项目根目录
BASE_DIR = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
# 添加系统参数
sys.path.append(os.path.abspath(os.path.join(BASE_DIR, 'backend')))  # 添加项目路径

from app.utils.logger import get_logger

from app.db.db_handler import get_database_handler
from app.db.db_models import User
from app.api.api_model import UserRegister

# 导入路由模块
from app.api.api_auth import router as auth_router
from app.api.api_user import router as user_router
from app.api.api_number import router as number_router
from app.api.api_info import router as info_router
from app.api.v1.api_version import router as api_version_v1
from app.api.v2.api_version import router as api_version_v2
# 导入数据库模块
from app.db.db_number import DBNumber
from app.db.db_auth import DBAuth
from app.api.api_number import db_dict as number_db_dict
from app.api.api_auth import db_dict as auth_db_dict

# 导入异常处理注册函数
from app.api.api_exception_handler import register_exception_handlers

from app.api.api_gRPC import serve_grpc  # 导入gRPC服务

from app.config import settings

app = FastAPI(debug=settings.DEBUG)

# 获取日志记录器实例
logger = get_logger()

# 注册全局异常处理器
register_exception_handlers(app)

# 初始化数据库迁移
db_handler = get_database_handler()
# db_handler.migrate_database()

# 实例化数据库
db_number = DBNumber(db_handler.get_session())
db_auth = DBAuth(db_handler.get_session())

db_dict = dict()
db_dict["db_number"] = db_number
db_dict["db_auth"] = db_auth

# 包含路由模块
app.include_router(auth_router)
app.include_router(user_router)
app.include_router(number_router)
app.include_router(info_router)
app.include_router(api_version_v1.router, prefix="/v1")
app.include_router(api_version_v2.router, prefix="/v2")

# 实例化的数据库给到对应文件
number_db_dict = db_dict
auth_db_dict = db_dict

# 实例化的数据库给到对应文件
number_db_dict = db_dict
auth_db_dict = db_dict

# 添加中间件来记录请求详情
@app.middleware("http")
async def log_requests(request: Request, call_next):
    """记录所有请求的详细信息"""
    # 记录请求开始
    logger.info(f"请求开始 - {request.method} {request.url}")
    # 记录请求头
    headers = dict(request.headers)
    logger.info(f"请求头: {headers}")
    # 记录请求体
    try:
        body = await request.body()
        if body:
            body_text = body.decode()
            logger.info(f"请求体: {body_text}")
    except Exception as e:
        logger.warning(f"无法读取请求体: {e}")
    # 记录查询参数
    if request.query_params:
        logger.info(f"查询参数: {dict(request.query_params)}")
    # 处理请求
    try:
        response = await call_next(request)
    except Exception as e:
        logger.exception(f"处理请求时发生异常: {e}")
        raise e
    # 记录响应状态
    logger.info(f"响应状态: {response.status_code}")
    
    # 如果响应是 StreamingResponse，重新创建以便读取内容
    if isinstance(response, StreamingResponse):
        buffer = io.BytesIO()
        async for chunk in response.body_iterator:
            buffer.write(chunk)
        body = buffer.getvalue().decode()
        logger.info(f"响应内容: {body}")
        response = StreamingResponse(io.BytesIO(buffer.getvalue()), media_type=response.media_type, status_code=response.status_code)
    
    return response

# 添加 CORS 中间件
app.add_middleware(
    CORSMiddleware,
    allow_origins=["http://localhost:5173"],  # 允许的前端源地址
    allow_credentials=True,  # 允许携带认证信息
    allow_methods=["*"],  # 允许所有 HTTP 方法
    allow_headers=["*"],  # 允许所有 HTTP 头
)

# 定义测试路由，用于测试 404 错误
@app.get("/test-404")
async def test_404():
    """
    测试路由，故意抛出 404 错误
    """
    raise HTTPException(status_code=404, detail="测试 404 错误")

# 定义启动服务器的异步函数
async def start_servers():
    """
    启动 gRPC 服务器和 FastAPI 服务器，使用 asyncio.gather 并发运行
    """
    # 启动 gRPC 服务器，传递默认地址 '[::]:50051'
    grpc_task = asyncio.create_task(serve_grpc())
    
    # 配置并启动 FastAPI 服务器
    config = uvicorn.Config(app, host="127.0.0.1", port=8000, log_level="debug")
    server = uvicorn.Server(config)
    fastapi_task = asyncio.create_task(server.serve())
    
    # 使用 gather 并发等待两个服务器任务
    await asyncio.gather(grpc_task, fastapi_task)

# 主入口，运行 start_servers 函数
if __name__ == "__main__":
    # 使用 asyncio.run 启动所有服务器
    asyncio.run(start_servers())
    
    # 如果不需要同时启动 gRPC 服务器，可以使用以下代码
    # 推荐通过命令行启动 Uvicorn，便于热重载和其他选项
    # uvicorn.run(app, host="127.0.0.1", port=8000, reload=True, log_level="debug")
    # uvicorn.run(app, host="127.0.0.1", port=8000)
